﻿using System;
using System.Threading;
using Microsoft.SPOT;
using Gadgeteer;

/*
 * Original Gadgeteer framework Copyright (c) Microsoft Corporation. (http://gadgeteer.codeplex.com/)
 * 
 * Gadgeteer Light made by Stefan Thoolen (http://gadgeteerlight.codeplex.com/)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
namespace GHI_Electronics_EBlock_Expansion
{
    public class Program
    {
        public static Gadgeteer.Interfaces.DigitalOutput Led;
        public static Gadgeteer.Interfaces.InterruptInput Button;
        public static Gadgeteer.Interfaces.AnalogInput Potmeter;
        public static Gadgeteer.Interfaces.PWMOutput Piezo;

        public static void Main()
        {
            // Use this demo to test D and O E-Block pins (requires a gadgeteer X or Y socket)
            LedButton(socket: 1, buttonPin: 3, ledPin: 4);

            // Use this demo to test E and O E-Block pins (requires a gadgeteer A socket)
            //LedPotentiometer(socket: 2, potmeterPin: 5, ledPin: 4);

            // Use this demo to test D and O E-Block pins (requires a gadgeteer P socket)
            //PiezoButton(socket: 3, buttonPin: 3, piezoPin: 9);
        }

        /// <summary>Led and button sample; when the button is pressed, the led will emit</summary>
        /// <param name="socket">[X Y] Gadgeteer socket of the E-Block module</param>
        /// <param name="buttonPin">(D) E-Block pin to which the button is connected</param>
        /// <param name="ledPin">(O) E-Block pin to which the led is connected</param>
        public static void LedButton(int socket, int buttonPin, int ledPin)
        {
            Gadgeteer.Modules.GHIElectronics.EBlockExpansion Exp = new Gadgeteer.Modules.GHIElectronics.EBlockExpansion(socket);

            Led = Exp.SetupDigitalOutput((Socket.Pin)ledPin, false);
            Button = Exp.SetupInterruptInput((Socket.Pin)buttonPin, Gadgeteer.Interfaces.GlitchFilterMode.On, Gadgeteer.Interfaces.ResistorMode.Disabled, Gadgeteer.Interfaces.InterruptMode.RisingAndFallingEdge);

            Button.Interrupt += new Gadgeteer.Interfaces.InterruptInput.InterruptEventHandler(LedButton_Interrupt);
            Thread.Sleep(Timeout.Infinite);
        }

        static void LedButton_Interrupt(Gadgeteer.Interfaces.InterruptInput sender, bool value)
        {
            Led.Write(!value);
        }

        /// <summary>Led and potentiometer sample; when the button is pressed, the led will emit</summary>
        /// <param name="socket">[A] Gadgeteer socket of the E-Block module</param>
        /// <param name="PotmeterPin">(A) E-Block pin to which the potentiometer is connected</param>
        /// <param name="ledPin">(O) E-Block pin to which the led is connected</param>
        public static void LedPotentiometer(int socket, int potmeterPin, int ledPin)
        {
            Gadgeteer.Modules.GHIElectronics.EBlockExpansion Exp = new Gadgeteer.Modules.GHIElectronics.EBlockExpansion(socket);

            Led = Exp.SetupDigitalOutput((Socket.Pin)ledPin, false);
            Potmeter = Exp.SetupAnalogInput((Socket.Pin)potmeterPin);

            while (true)
            {
                Led.Write(true);
                Thread.Sleep((int)(Potmeter.ReadProportion() * 1000));
                Led.Write(false);
                Thread.Sleep((int)(Potmeter.ReadProportion() * 1000));
            }
        }

        /// <summary>Button and piezo sample; when the button is pressed, the piezo will make sounds</summary>
        /// <param name="socket">[P] Gadgeteer socket of the E-Block module</param>
        /// <param name="buttonPin">(D) E-Block pin to which the button is connected</param>
        /// <param name="PiezoPin">(O) E-Block pin to which the piezo is connected</param>
        public static void PiezoButton(int socket, int buttonPin, int piezoPin)
        {
            Gadgeteer.Modules.GHIElectronics.EBlockExpansion Exp = new Gadgeteer.Modules.GHIElectronics.EBlockExpansion(socket);

            Piezo = Exp.SetupPWMOutput((Socket.Pin)piezoPin);
            Button = Exp.SetupInterruptInput((Socket.Pin)buttonPin, Gadgeteer.Interfaces.GlitchFilterMode.On, Gadgeteer.Interfaces.ResistorMode.Disabled, Gadgeteer.Interfaces.InterruptMode.RisingAndFallingEdge);
            
            Button.Interrupt += new Gadgeteer.Interfaces.InterruptInput.InterruptEventHandler(PiezoButton_Interrupt);
            Thread.Sleep(Timeout.Infinite);
        }

        // Tone ladder
        static uint[] PiezoNotes = { 1915000, 1700000, 1519000, 1432000, 1275000, 1136000, 1014000, 956000, 851000, 758000 };
        // Current index on the tone ladder
        static int PiezoIndex = 0;

        static void PiezoButton_Interrupt(Gadgeteer.Interfaces.InterruptInput sender, bool value)
        {
            if (!value)
            {
                // Fetches the current note
                uint Note = PiezoNotes[PiezoIndex];
                // Configues the PWM port
                Piezo.SetPulse(Note * 2, Note);
                // Let it play for 0.5 sec
                Piezo.Active = true;
                Thread.Sleep(500);
                Piezo.Active = false;
                // Decides which note should be next
                ++PiezoIndex;
                if (PiezoIndex == PiezoNotes.Length) PiezoIndex = 0;
            }
        }

    }
}
